import { Graphics, Mask, MaskType, NodeEventType, Sprite, UITransform, Widget } from "cc";

// 修正Widget BUG
const proto = Widget.prototype as any;
proto._unregisterOldParentEvents = function(oldParent: Node) {
    const target = this._target || oldParent;
    if (target) {
        target.off(NodeEventType.TRANSFORM_CHANGED, this._setDirtyByMode, this);
        target.off(NodeEventType.SIZE_CHANGED, this._setDirtyByMode, this);
        target.off(NodeEventType.ANCHOR_CHANGED, this._setDirtyByMode, this);
    }
};

// 1. 获取原始的属性描述符
const originalMaskTypeDescriptor = Object.getOwnPropertyDescriptor(Mask.prototype, 'type');

// 2. 创建新的 setter 实现
const newSetter = function (this: any, value: MaskType) {
    // 添加新的自定义逻辑
    console.log(`New logic executed for value: ${value}`);
    // 这里可以添加更多自定义操作
    if (this._type === value) {
        return;
    }

    if (value !== MaskType.SPRITE_STENCIL) {
        if (this._sprite) {
            this.node.removeComponent(Sprite);
            this.node._uiProps.uiComp = null;
            // this._sprite._destroyImmediate();  // 不能立即销毁，否则可能导致onEnable出错
            this._sprite = null;
        }
    } else {
        if (this._graphics) {
            this._graphics.clear();
            this.node.removeComponent(Graphics);
            this.node._uiProps.uiComp = null;
            // this._graphics._destroyImmediate(); // 不能立即销毁，否则可能导致onEnable出错
            this._graphics = null;
        }
    }
    if (originalMaskTypeDescriptor.set) {
        originalMaskTypeDescriptor.set.call(this, value);
    }
};

// 3. 覆盖原型链上的属性
Object.defineProperty(Mask.prototype, 'type', {
    ...originalMaskTypeDescriptor,       // 保留原始配置
    set: newSetter               // 替换 set 方法
});

const uiTrans_proto = UITransform.prototype;
const origin_uitrans_onDestroy = uiTrans_proto.onDestroy;
uiTrans_proto.onDestroy = function() {
    const map = (<any>UITransform).priorityChangeNodeMap as Map<string, Node>;
    const key = this.node.uuid;
    if (map.has(key)) map.delete(key);
    origin_uitrans_onDestroy.call(this);
}